package com.yuns.util;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * 解析excel
 * @author liuchengwen
 * @create 2019-08-12
 */
public class ImportExcelUtil {

    /**
     *
     * @param path 路径
     * @param firstIndex
     * @param aimClass
     * @param <T>
     * @return
     */
    public <T> List<T> parseFromExcel(String path, int firstIndex, Class<T> aimClass) {
        List<T> result = new ArrayList<T>();
        try {
            FileInputStream inputStream = new FileInputStream(path);
            analysisExcel(inputStream, firstIndex, aimClass, result);
            inputStream.close();
            return result;
        } catch (
                Exception e) {
            e.printStackTrace();
            System.err.println("An error occured when parsing object from Excel. at " + this.getClass());
        }
        return result;
    }

    /**
     *
     * @param inputStream 输入流
     * @param firstIndex
     * @param aimClass
     * @param <T>
     * @return
     */
    public <T> List<T> parseFromExcel(InputStream inputStream, int firstIndex, Class<T> aimClass) {
        List<T> result = new ArrayList<T>();
        try {
            analysisExcel(inputStream, firstIndex, aimClass, result);
            inputStream.close();
            return result;
        } catch (
                Exception e) {
            e.printStackTrace();
            System.err.println("An error occured when parsing object from Excel. at " + this.getClass());
        }
        return result;
    }

    private <T> void analysisExcel(InputStream inputStream, int firstIndex, Class<T> aimClass, List<T> result) throws IOException, InvalidFormatException, InstantiationException, IllegalAccessException {
        Workbook workbook = WorkbookFactory.create(inputStream);
        //对excel文档的第一页,即sheet1进行操作
        Sheet sheet = workbook.getSheetAt(0);
        int lastRaw = sheet.getLastRowNum();
        for (int i = firstIndex; i < lastRaw+1; i++) {
            //第i行
            Row row = sheet.getRow(i);
            T parseObject = aimClass.newInstance();
            Field[] fields = aimClass.getDeclaredFields();
            for (int j = 0; j < fields.length; j++) {
                Field field = fields[j];
                field.setAccessible(true);
                Class<?> type = field.getType();
                //第j列
                Cell cell = row.getCell(j);
                if (cell == null)
                    continue;
                //很重要的一行代码,如果不加,像12345这样的数字是不会给你转成String的,只会给你转成double,而且会导致cell.getStringCellValue()报错
                cell.setCellType(Cell.CELL_TYPE_STRING);
                String cellContent = cell.getStringCellValue();
                cellContent = "".equals(cellContent) ? "0" : cellContent;
                if (type.equals(String.class)) {
                    field.set(parseObject, cellContent);
                } else if (type.equals(char.class) || type.equals(Character.class)) {
                    field.set(parseObject, cellContent.charAt(0));
                } else if (type.equals(int.class) || type.equals(Integer.class)) {
                    field.set(parseObject, Integer.parseInt(cellContent));
                } else if (type.equals(long.class) || type.equals(Long.class)) {
                    field.set(parseObject, Long.parseLong(cellContent));
                } else if (type.equals(float.class) || type.equals(Float.class)) {
                    field.set(parseObject, Float.parseFloat(cellContent));
                } else if (type.equals(double.class) || type.equals(Double.class)) {
                    field.set(parseObject, Double.parseDouble(cellContent));
                } else if (type.equals(short.class) || type.equals(Short.class)) {
                    field.set(parseObject, Short.parseShort(cellContent));
                } else if (type.equals(byte.class) || type.equals(Byte.class)) {
                    field.set(parseObject, Byte.parseByte(cellContent));
                } else if (type.equals(boolean.class) || type.equals(Boolean.class)) {
                    field.set(parseObject, Boolean.parseBoolean(cellContent));
                }
            }
            result.add(parseObject);
        }
    }

    /**
     * 校验对象属性是否都为null
     * @param obj 对象
     * @return
     * @throws Exception
     */
    public  static boolean isAllFieldNull(Object obj){
        Class stuCla = (Class) obj.getClass();// 得到类对象
        Field[] fs = stuCla.getDeclaredFields();//得到属性集合
        boolean flag = true;
        for (Field f : fs) {//遍历属性
            f.setAccessible(true); // 设置属性是可以访问的(私有的也可以)
            Object val = null;// 得到此属性的值
            try {
                val = f.get(obj);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            if(val!=null) {//只要有1个属性不为空,那么就不是所有的属性值都为空
                flag = false;
                break;
            }
        }
        return flag;
    }

}
